﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.IO;
using System.Text.RegularExpressions;

using DataReceiver.DataAPI;
using Core.Common;
using XAPI;
using XAPI.Callback;

namespace DataReceiver.BgReceiver
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                //缓冲
                TickFilter filter = new TickFilter();
                filter.OnTicksMoveing += (List<Model_Tick> ticks) => { MongoOperater.InsertTicks(ticks); };

                #region 获取合约，订阅行情
                //初始化行情接口
                Model_MdAccount mdAccount = DataReceiver.DataAPI.ConfigHelper.MdAccounts[0];
                string mdPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "CTP_Quote_x86.dll");
                XApi mdApi = new XApi(mdPath);
                mdApi.Server.Address = mdAccount.Server;
                mdApi.Server.BrokerID = mdAccount.BrokerID;
                mdApi.User.UserID = mdAccount.InverstorID;
                mdApi.User.Password = mdAccount.Passwd;

                mdApi.OnConnectionStatus = (object sender, ConnectionStatus status, ref RspUserLoginField userLogin, int size1) =>
                {
                    LogTextHelper.WriteLine("行情状态:" + status.ToString());
                };

                mdApi.OnRtnDepthMarketData = (object sender, ref DepthMarketDataNClass marketData) =>
                {
                    Model_Tick tick = new Model_Tick()
                    {
                        InstrumentID = marketData.InstrumentID
                        ,
                        AskPrice = marketData.Asks.Length > 0 ? marketData.Asks[0].Price : -1
                        ,
                        AskVolume = marketData.Asks.Length > 0 ? marketData.Asks[0].Size : -1
                        ,
                        BidPrice = marketData.Bids.Length > 0 ? marketData.Bids[0].Price : -1
                        ,
                        BidVolume = marketData.Bids.Length > 0 ? marketData.Bids[0].Size : -1
                        ,
                        LastPrice = marketData.LastPrice
                        ,
                        OpenInterest = marketData.OpenInterest
                        ,
                        UpdateTime = new DateTime(
                            marketData.ActionDay / 10000
                            , marketData.ActionDay / 100 % 100
                            , marketData.ActionDay % 100
                            , marketData.UpdateTime / 10000
                            , marketData.UpdateTime / 100 % 100
                            , marketData.UpdateTime % 100
                            , marketData.UpdateMillisec)
                        ,
                        Volume = Convert.ToInt32(marketData.Volume)
                    };

                    filter.AddTick(tick);
                };

                mdApi.Connect();
                Thread.Sleep(5 * 1000);

                //初始化交易接口
                Model_TdAccount tdAccount = DataReceiver.DataAPI.ConfigHelper.TdAccount;
                string tdPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "CTP_Trade_x86.dll");
                XApi tdApi = new XApi(tdPath);
                tdApi.Server.Address = tdAccount.Server;
                tdApi.Server.BrokerID = tdAccount.BrokerID;
                tdApi.Server.PrivateTopicResumeType = ResumeType.Quick;
                tdApi.User.UserID = tdAccount.InverstorID;
                tdApi.User.Password = tdAccount.Passwd;

                tdApi.OnConnectionStatus = (object sender, ConnectionStatus status, ref RspUserLoginField userLogin, int size1) =>
                {
                    LogTextHelper.WriteLine("交易状态:" + status.ToString());
                    if (status == ConnectionStatus.Done)
                    {
                        ReqQueryField query = default(ReqQueryField);
                        tdApi.ReqQuery(QueryType.ReqQryInstrument, ref query);
                    }
                };

                tdApi.OnRspQryInstrument = (object sender, ref InstrumentField instrument, int size1, bool bIsLast) =>
                {
                    //只订阅期货，并且不订阅套利等其他合约
                    Regex re = new Regex(@"^[a-zA-Z]+\d+$", RegexOptions.None);
                    if (instrument.Type == InstrumentType.Future
                        && re.IsMatch(instrument.InstrumentID))
                    {
                        LogTextHelper.WriteLine("查询合约成功：" + instrument.InstrumentID);
                        mdApi.Subscribe(instrument.InstrumentID, instrument.ExchangeID);
                    }
                };

                tdApi.OnRspQrySettlementInfo = (object sender, ref SettlementInfoClass settlementInfo, int size1, bool bIsLast) =>
                {
                    LogTextHelper.WriteLine("OnRspQrySettlementInfo:" + settlementInfo.Content);
                };

                tdApi.Connect();
                Thread.Sleep(30 * 1000);
                #endregion

                #region  定时退出（只在正确时）
                //定义为收盘，或者掉线退出
                while (tdApi.IsConnected && mdApi.IsConnected)
                {
                    Thread.Sleep(60 * 1000);
                    int timeNumber = DateTime.Now.Hour * 100 + DateTime.Now.Minute;
                    if ((timeNumber > 1530 && timeNumber < 1545)
                        || (timeNumber > 245 && timeNumber < 300))
                    {
                        break;
                    }
                }

                tdApi.Dispose();
                mdApi.Dispose();
                Thread.Sleep(10 * 1000);
                LogTextHelper.WriteLine("程序退出");
                #endregion
            }
            catch (Exception e)
            {
                LogTextHelper.WriteLine("全局异常：" + e.Message);
            }
        }
    }
}
